package co.edu.pedagogica.recibo;

import co.edu.pedagogica.recibo.helper.CodigoDeBarras;
import co.edu.pedagogica.recibo.helper.ElementoPDF;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.DottedLineSeparator;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Map;

/**
 *
 * @author Juan Sebastian Hernández Serrato
 */
public class Recibo {
    
    private String referenciaDePago;
    private long numeroDeRecibo;
    private String programa;
    private String periodo;
    private Calendar fechaDeExpedicion;
    private Calendar fechaLimiteDePago;
    private Calendar fechaDeVencimiento;
    private long valorRecibo;
    private long valorSaldo;
    private long valorTotal;
    private String cifra;
    private String centroDeCostos;
    private String cabecera;
    private String pie;
    private Image logo;
    private String documento;
    private String nombre;
    
    private Map<String, Long> conceptos;
    
    public Document obtenerRecibo(OutputStream salida) {
        Document document = new Document(PageSize.LETTER);
        try{
            PdfWriter writer = PdfWriter.getInstance(document, salida);
            document.open();
            document.add(obtenerParte(writer,true,false,"Estudiante"));
            document.add(new Chunk(new DottedLineSeparator()));
            document.add(obtenerParte(writer,true,false,centroDeCostos));
            document.add(new Chunk(new DottedLineSeparator()));
            document.add(obtenerParte(writer,false,true,"Banco Caja Social"));
            document.close();
        }catch(Exception e){
            e.printStackTrace();
        }
        finally{
            return document;
        }
    }    

    public String getReferenciaDePago() {
        return referenciaDePago;
    }

    public void setReferenciaDePago(String referenciaDePago) {
        this.referenciaDePago = referenciaDePago;
    }

    public long getNumeroDeRecibo() {
        return numeroDeRecibo;
    }

    public void setNumeroDeRecibo(long numeroDeRecibo) {
        this.numeroDeRecibo = numeroDeRecibo;
    }

    public String getPrograma() {
        return programa;
    }

    public void setPrograma(String programa) {
        this.programa = programa;
    }

    public String getPeriodo() {
        return periodo;
    }

    public void setPeriodo(String periodo) {
        this.periodo = periodo;
    }

    public Calendar getFechaDeExpedicion() {
        return fechaDeExpedicion;
    }

    public void setFechaDeExpedicion(Calendar fechaDeExpedicion) {
        this.fechaDeExpedicion = fechaDeExpedicion;
    }

    public Calendar getFechaLimiteDePago() {
        return fechaLimiteDePago;
    }

    public void setFechaLimiteDePago(Calendar fechaLimiteDePago) {
        this.fechaLimiteDePago = fechaLimiteDePago;
    }

    public Calendar getFechaDeVencimiento() {
        return fechaDeVencimiento;
    }

    public void setFechaDeVencimiento(Calendar fechaDeVencimiento) {
        this.fechaDeVencimiento = fechaDeVencimiento;
    }

    public long getValorRecibo() {
        return valorRecibo;
    }

    public void setValorRecibo(long valorRecibo) {
        this.valorRecibo = valorRecibo;
    }

    public long getValorSaldo() {
        return valorSaldo;
    }

    public void setValorSaldo(long valorSaldo) {
        this.valorSaldo = valorSaldo;
    }

    public long getValorTotal() {
        return valorTotal;
    }

    public void setValorTotal(long valorTotal) {
        this.valorTotal = valorTotal;
    }

    public String getCifra() {
        return cifra;
    }

    public void setCifra(String cifra) {
        this.cifra = cifra;
    }

    public String getCentroDeCostos() {
        return centroDeCostos;
    }

    public void setCentroDeCostos(String centroDeCostos) {
        this.centroDeCostos = centroDeCostos;
    }

    public String getCabecera() {
        return cabecera;
    }

    public void setCabecera(String cabecera) {
        this.cabecera = cabecera;
    }
    
    public String getPie(){
        return pie;
    }
    
    public void setPie(String pie){
        this.pie = pie;
    }

    public Image getLogo() {
        // 70x100
        return logo;
    }

    
    public void setLogo(Image logo) {
        this.logo = logo;
    }

    public String getDocumento() {
        return documento;
    }

    public void setDocumento(String documento) {
        this.documento = documento;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public Map<String, Long> getConceptos() {
        return conceptos;
    }

    public void setConceptos(Map<String, Long> conceptos) {
        this.conceptos = conceptos;
    }
    
    public Paragraph obtenerParte(PdfWriter writer, boolean mostrarConceptos, 
            boolean mostrarCodigosDeBarras, String notaMargen) throws DocumentException{
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
                
        Paragraph parrafo = new Paragraph();
        
        PdfPTable tablaPrincipal = new PdfPTable(2);
        tablaPrincipal.setWidthPercentage(100);
        tablaPrincipal.setWidths(new int[]{20,1});
        
        PdfPTable tablaCabecera = new PdfPTable(3);
        tablaCabecera.setWidthPercentage(100);
        tablaCabecera.setWidths(new int[]{1,2,2});
        if(logo != null){
            tablaCabecera.addCell(ElementoPDF.celda(logo, false));
            tablaCabecera.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(cabecera, 8), false, 1, 4, PdfPCell.ALIGN_CENTER));
        }else{
            tablaCabecera.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(cabecera, 8), false, 2, 4, PdfPCell.ALIGN_CENTER));
        }
        PdfPTable tablaDatosBasicosRecibo = new PdfPTable(2);
        tablaDatosBasicosRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Referencias de pago:"), false));
        tablaDatosBasicosRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(referenciaDePago), false, PdfPCell.ALIGN_RIGHT));
        tablaDatosBasicosRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Periodo: "), false));
        tablaDatosBasicosRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(periodo), false, PdfPCell.ALIGN_RIGHT));
        tablaDatosBasicosRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Expedido: "), false));
        tablaDatosBasicosRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(df.format(fechaDeExpedicion.getTime())), false, PdfPCell.ALIGN_RIGHT));
        tablaDatosBasicosRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Vence: "), false));
        tablaDatosBasicosRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(df.format(fechaDeVencimiento.getTime())), false, PdfPCell.ALIGN_RIGHT));
        
        tablaCabecera.addCell(tablaDatosBasicosRecibo);
        parrafo.add(tablaCabecera);
        
        PdfPTable tablaDeInformacionPersonal = new PdfPTable(2);
        tablaDeInformacionPersonal.setWidthPercentage(100);
        tablaDeInformacionPersonal.setWidths(new int[]{2,1});
        
        tablaDeInformacionPersonal.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Estudiante: " + nombre),false));
        tablaDeInformacionPersonal.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Documento: " + documento),false));
        tablaDeInformacionPersonal.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Curso: " + programa),false, 2, 1));
        
        parrafo.add((tablaDeInformacionPersonal));
        
        PdfPTable tablaDeInformacionFinanciera = new PdfPTable(2);
        tablaDeInformacionFinanciera.setWidthPercentage(100);
        tablaDeInformacionFinanciera.setWidths(new int[]{11,7});
        
        PdfPCell celdaIzquierdaFinanciera = ElementoPDF.celda(new Paragraph(), false);
        
        if(mostrarConceptos){
            PdfPTable tablaDeConceptos = new PdfPTable(2);
            tablaDeConceptos.setWidths(new int[]{3,1});
            tablaDeConceptos.setWidthPercentage(100);
            
            tablaDeConceptos.addCell(ElementoPDF.celda(new Paragraph("Concepto", new Font(FontFactory.getFont("Courier", 8, Font.BOLD, BaseColor.BLACK))),false));
            tablaDeConceptos.addCell(ElementoPDF.celda(new Paragraph("Valor", new Font(FontFactory.getFont("Courier", 8, Font.BOLD, BaseColor.BLACK))),false));
            
            for(Map.Entry<String, Long> concepto : conceptos.entrySet() ){
                tablaDeConceptos.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(concepto.getKey()),false));
                tablaDeConceptos.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(concepto.getValue().toString()),false));
            }
            celdaIzquierdaFinanciera.addElement(tablaDeConceptos);
        }
        
        if(mostrarCodigosDeBarras){
            celdaIzquierdaFinanciera.addElement(ElementoPDF.crearParrafo(" "));
            
            celdaIzquierdaFinanciera.addElement(ElementoPDF.crearParrafo("Valor " +  periodo));
            Barcode codigoDeBarras = new Barcode128();
            codigoDeBarras.setCodeType(Barcode.CODE128_UCC);
            codigoDeBarras.setCode(CodigoDeBarras.generarCodigo(valorRecibo, referenciaDePago, fechaDeVencimiento));
            celdaIzquierdaFinanciera.addElement(codigoDeBarras.createImageWithBarcode(writer.getDirectContent(), BaseColor.BLACK, BaseColor.BLACK));

            if(valorSaldo != 0){
                celdaIzquierdaFinanciera.addElement(ElementoPDF.crearParrafo("Valor Total"));
                codigoDeBarras = new Barcode128();
                codigoDeBarras.setCodeType(Barcode.CODE128_UCC);
                codigoDeBarras.setCode(CodigoDeBarras.generarCodigo(valorTotal, referenciaDePago, fechaDeVencimiento));
                celdaIzquierdaFinanciera.addElement(codigoDeBarras.createImageWithBarcode(writer.getDirectContent(), BaseColor.BLACK, BaseColor.BLACK));
            }
        }
        tablaDeInformacionFinanciera.addCell(celdaIzquierdaFinanciera);
        
        PdfPTable tablaValoresRecibo = new PdfPTable(2);
        tablaValoresRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Valor: "), false));
        tablaValoresRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(""+valorRecibo), false, PdfPCell.ALIGN_RIGHT));
        tablaValoresRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Saldo: "), false));
        tablaValoresRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(""+valorSaldo), false, PdfPCell.ALIGN_RIGHT));
        tablaValoresRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo("Valor Total: "), false));
        tablaValoresRecibo.addCell(ElementoPDF.celda(ElementoPDF.crearParrafo(""+valorTotal), false, PdfPCell.ALIGN_RIGHT));
        
        PdfPCell celdaDerechaFinanciera = ElementoPDF.celda(new Paragraph(), false);
        celdaDerechaFinanciera.addElement(tablaValoresRecibo);
        celdaDerechaFinanciera.addElement(ElementoPDF.crearParrafo("Cuenta recaudadora: Banco Caja Social Cta. Ahorros\n"
                    + "Nombre de la cuenta: Universidad Pedagógica Nacional\n"
                    + "Convenio: 18960", Font.FontFamily.TIMES_ROMAN, 8));
        celdaDerechaFinanciera.addElement(ElementoPDF.crearParrafo("*"+pie, Font.FontFamily.TIMES_ROMAN, 6));
        tablaDeInformacionFinanciera.addCell(celdaDerechaFinanciera);
        
        parrafo.add(tablaDeInformacionFinanciera);

        Font font = new Font();
        font.setColor(BaseColor.LIGHT_GRAY);
        
        PdfPCell celdaContenido = new PdfPCell();
        celdaContenido.setBorder(PdfPCell.NO_BORDER);
        celdaContenido.addElement(parrafo);
        tablaPrincipal.addCell(celdaContenido);
        
        PdfPCell celdaLateral = new PdfPCell(new Paragraph(notaMargen, font));
        celdaLateral.setRotation(90);
        celdaLateral.setVerticalAlignment(Element.ALIGN_MIDDLE);
        celdaLateral.setBorder(PdfPCell.NO_BORDER);
        tablaPrincipal.addCell(celdaLateral);
        
        Paragraph contenido = new Paragraph();
        contenido.add(tablaPrincipal);
        
        return contenido;
    }
}